package org.zachary.creditbusiness.hotel.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zachary.creditbusiness.hotel.entity.Reservation;
import org.zachary.creditbusiness.hotel.mapper.ReservationMapper;
import org.zachary.commonmodule.entity.MqTransmissionJson;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class SendReservation {

    private static final int    DEFAULT_SERVICE_TYPE   = 4;

    private static final DateTimeFormatter FORMATTER =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Autowired
    private ReservationMapper reservationMapper;

    @Autowired
    private KafkaProducerService kafkaProducerService;

    /**
     * 根据订单ID查询数据库，并将对应信息组装成 MqTransmissionJson 发到 Kafka。
     *
     * @param orderId 订单主键
     */
    public void sendMessage(Integer orderId) {
        // 1. 查询订单（MyBatis-Plus 自动映射 String 日期字段）
        Reservation res = reservationMapper.selectById(orderId);
        if (res == null) {
            throw new IllegalArgumentException("未找到订单，orderId=" + orderId);
        }

        // 2. 逾期 & 支付状态、金额
        boolean isOverdue = false;
        boolean isPaid    = true;
        double  amount    = res.getPrice() != null ? res.getPrice() : 0.0;

        // 3. 转换 String -> Instant（按北京时区）
        Instant dueTime    = parseToInstant(res.getCheckoutDate());
        Instant finishTime = parseToInstant(res.getPayDate());

        int overduePeriod=calculatePeriod(dueTime,finishTime);


        // 4. 构建并发送
        MqTransmissionJson payload = new MqTransmissionJson(
                UUIdUtil.createUUId(),
                res.getUserId(),
                DEFAULT_SERVICE_TYPE,
                isOverdue,
                overduePeriod,
                isPaid,
                amount,
                "酒店预订-按时还款订单",
                dueTime,
                finishTime
                // 刚逾期未还款： isOverdue = true, overduePeriod=-1, isPaid =true , amount=0.0, finishTime=null
                // 逾期后还款： isOverdue = true, overduePeriod>0, isPaid =true , amount>0, finishTime!=null
        );
        log.info("检测到守约还款");
        kafkaProducerService.sendJsonMessage("TestTopic", payload);
    }

    public void sendMessage2(Integer orderId) {
        // 1. 查询订单（MyBatis-Plus 自动映射 String 日期字段）
        Reservation res = reservationMapper.selectById(orderId);
        if (res == null) {
            throw new IllegalArgumentException("未找到订单，orderId=" + orderId);
        }

        // 2. 逾期 & 支付状态、金额
        boolean isOverdue = true;
        boolean isPaid    = true;
        double  amount    = res.getPrice() != null ? res.getPrice() : 0.0;

        // 3. 转换 String -> Instant（按北京时区）
        Instant dueTime    = parseToInstant(res.getCheckoutDate());
        Instant finishTime = parseToInstant(res.getPayDate());

        int overduePeriod=calculatePeriod(dueTime,finishTime);


        // 4. 构建并发送
        MqTransmissionJson payload = new MqTransmissionJson(
                res.getUuid(),
                res.getUserId(),
                DEFAULT_SERVICE_TYPE,
                isOverdue,
                overduePeriod,
                isPaid,
                amount,
                "酒店预订-逾期还款订单",
                dueTime,
                finishTime
                // 刚逾期未还款： isOverdue = true, overduePeriod=-1, isPaid =true , amount=0.0, finishTime=null
                // 逾期后还款： isOverdue = true, overduePeriod>0, isPaid =true , amount>0, finishTime!=null
        );
        log.info("检测到逾期还款");
        kafkaProducerService.sendJsonMessage("TestTopic", payload);
    }

    /**
     * 把格式为 "yyyy-MM-dd HH:mm:ss" 的本地时间字符串，
     * 视为北京时区时间，转换到 UTC 对应的 Instant。
     */
    private Instant parseToInstant(String dateStr) {
        LocalDateTime ldt = LocalDateTime.parse(dateStr, FORMATTER);
        return ldt.atZone(ZoneId.of("Asia/Shanghai")).toInstant();
    }

    private int calculatePeriod(Instant due, Instant finish) {
        if (!finish.isAfter(due)) {
            return 0;
        }
        long days = ChronoUnit.DAYS.between(due, finish);
        if (days <= 7) {
            return 1;
        } else if (days <= 30) {
            return 2;
        } else if (days <= 90) {
            return 3;
        } else if (days <= 180) {
            return 4;
        } else {
            return 5;
        }
    }

}